#ifndef __ISERVICE_CLASS_FACTORY_IMPL_H__
#define __ISERVICE_CLASS_FACTORY_IMPL_H__

#include "../common/include/class_factory_ifaces.h"
#include "../common/include/registry_ifaces.h"
#include "../common/include/cls_ids.h"
#include "../../include/co_class_base.h"
#include "../../include/ref_obj_ptr.h"
#include "../../include/module_holder.h"
#include "../../include/pulsed_thread.h"

#include <map>
#include <string>
#include <ctime>
#include <memory>

namespace Boss
{

  class IClassFactoryImpl
    : public CoClassBase
        <
          TL::TypeListAdapter
            <
              IClassFactory,
              IClassFactoryCtrl
            >
        >
  {
  public:
    BOSS_DECLARE_STR_CLSID(BOSS_CLSID_ICLASSFACTORYIMPL)

    // IClassFactory
    virtual TResult BOSS_CALL_TYPE CreateObject(TGuid coClassId, TPtr *instance);

    // IClassFactoryCtrl
    virtual TResult BOSS_CALL_TYPE SetRegistry(IServiceRegistry *registry);

    bool FinalizeCreate();
    void BeforeDestroy();

  private:
    typedef SharedPtr<ModuleHolder> ModuleHolderPtr;
    typedef std::pair<ModuleHolderPtr, std::time_t> ModulePair;
    typedef SharedPtr<ModulePair> ModulePairPtr;
    typedef std::map<std::string, ModulePairPtr> ModulePool;
    typedef std::map<std::string, std::string> CoClassModulePool;

    static const double ModuleLifeTime;
    static const ULong CleanTimeout;

    CoClassModulePool CoClassToModuleId;
    ModulePool Modules;
    RefObjPtr<IServiceRegistry> Registry;

    std::auto_ptr<PulsedThread> CleanerThread;
    void Cleaner();
  };

}

#endif  // !__ISERVICE_CLASS_FACTORY_IMPL_H__
